
package com.be.beadmin.system.impl;

import com.be.beadmin.common.entity.PageEntity;
import com.be.beadmin.common.utils.JpaQueryBuilder;
import com.be.beadmin.common.utils.JpaSortBuilder;
import com.be.beadmin.material.dto.output.PickingTaskEx;
import com.be.beadmin.material.entity.PickingTask;
import com.be.beadmin.material.entity.PickingTask_;
import com.be.beadmin.material.mapper.PickingTaskMapperEx;
import com.be.beadmin.material.repository.PickingTaskRepository;
import com.be.beadmin.product.dto.output.PlantCapacityCalendarEx;
import com.be.beadmin.product.dto.output.ProductManufactInforEx;
import com.be.beadmin.product.dto.output.WorkOrderInforEx;
import com.be.beadmin.product.entity.PlantCapacityCalendar;
import com.be.beadmin.product.entity.ProductManufactInfor;
import com.be.beadmin.product.entity.WorkOrderInfor;
import com.be.beadmin.product.mapper.ErrorReportMapperEx;
import com.be.beadmin.product.mapper.PlantCapacityCalendarMapperEx;
import com.be.beadmin.product.mapper.ProductManufactInforMapperEx;
import com.be.beadmin.product.mapper.WorkOrderInforMapperEx;
import com.be.beadmin.product.repository.PlantCapacityCalendarRepository;
import com.be.beadmin.product.repository.ProductManufactInforRepository;
import com.be.beadmin.product.repository.WorkOrderInforRepository;
import com.be.beadmin.project.entity.BatchPlan;
import com.be.beadmin.project.entity.BatchProduct;
import com.be.beadmin.project.entity.PlanStage;
import com.be.beadmin.project.repository.BatchPlanRepository;
import com.be.beadmin.project.repository.BatchProductRepository;
import com.be.beadmin.project.service.BatchPlanService;
import com.be.beadmin.project.service.InfoService;
import com.be.beadmin.quality.entity.CabinetQuality;
import com.be.beadmin.quality.entity.CustomComplaint;
import com.be.beadmin.quality.repository.CabinetQualityRepository;
import com.be.beadmin.quality.repository.CustomComplaintRepository;
import com.be.beadmin.system.repository.ReportFormsRepostiory;
import com.be.beadmin.system.service.ReportFormsService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import com.be.beadmin.product.entity.*;

import javax.annotation.Resource;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;

/**
 * @description 服务实现
 * @author ljh
 * @date 2023-04-21
 **/
@Service
@RequiredArgsConstructor
public class ReportFormsimpl implements ReportFormsService {
    @Autowired
    private ReportFormsRepostiory reportFormsRepostiory;
    @Autowired
    private ErrorReportMapperEx errorReportExMapper;

    @Override
    public Map<String, Object> getReportformsErrorReportByPage() {
        Map<String, Object> result = new HashMap<>();
        List<String> typeList = Arrays.asList("BOM异常", "客户现场异常", "其他异常", "设备/工具异常", "生产异常", "图纸异常", "物料异常");
        List<Map<String, Object>> varList = new ArrayList<>();
        for (String type : typeList) {
            Long count = reportFormsRepostiory.count((root, criteriaQuery, criteriaBuilder) -> {
                List<Predicate> list = new ArrayList<>();
                Predicate pre1 = criteriaBuilder.equal(root.get(ErrorReport_.errorType), type);
                list.add(pre1);
                Predicate pre2 = criteriaBuilder.equal(root.get(ErrorReport_.delete), 0); //过滤为0
                list.add(pre2);
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            });
            Map<String, Object> var = new HashMap<>();
            if (count>0)
            {
                var.put("name", type);
                var.put("value", count);
                varList.add(var);
            }
        }
        result.put("result", "success");
        result.put("typeList", typeList);
        result.put("varList", varList);
        return result;
    }

    @Autowired
    private InfoService infoService;
    @Autowired
    private WorkOrderInforRepository workOrderInforRepository;
    @Autowired
    private WorkOrderInforMapperEx workOrderInforExMapper;
    @Autowired
    private BatchPlanRepository batchPlanRepository;
    @Autowired
    private BatchPlanService batchPlanService;
    @Autowired
    private BatchProductRepository batchProductRepository;

    @Override
    public double[] getReportformsWorkOrderInforObjectByPage() {
        PageEntity pageEntity = new PageEntity();
        pageEntity.setCurrent(1);
        double inf = Double.POSITIVE_INFINITY;
        pageEntity.setPageSize((int) inf);
        pageEntity.setSorters(new ArrayList<>());
        pageEntity.setFilters(new ArrayList<>());
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<WorkOrderInfor> page = workOrderInforRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
//                    boolean isAdmin = false;
//                    for (Role role : userService.getRolesByCurrentUser(request)) {
//                        if (role.getCode().equals("ROLE_Admin")) {
//                            isAdmin = true;
//                        }
//                    }
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(WorkOrderInfor_.delete), 0); //过滤为0
                    list.add(pre2);
                    // 如果是系统管理员，所有的都可以看
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(WorkOrderInfor_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<WorkOrderInforEx> page2 = page.map(new Function<WorkOrderInfor, WorkOrderInforEx>() {
            @Override
            public WorkOrderInforEx apply(WorkOrderInfor workOrderInfor) {
//                    System.out.println(workOrderInforEx.toString());
                BatchProduct product = batchProductRepository.findBatchProductByIdAndDelete(workOrderInfor.getBatchProductId(), 0);

                if (product == null) {
                    workOrderInfor.setDelete(1);
                    workOrderInforRepository.save(workOrderInfor);
                    return null;
                }
                // 需要获取到工单的状态和预警状态
                // 状态--- 根据所有工序的开始和结束状态检查。

                WorkOrderInforEx workOrderInforEx = workOrderInforExMapper.toEntity(workOrderInfor);
                // 工单的计划开始和结束时间以及交付时间都设置为批次计划的时间
                BatchPlan plan = batchPlanRepository.findBatchPlanByIdAndDelete(product.getBatchPlanId(), 0);
                if (plan == null) {
                    workOrderInforEx.setPlanManufactStartDate(null);
                    workOrderInforEx.setPlanManufactEndDate(null);
                    workOrderInforEx.setBatchDeliveryDate(null);
                } else {
                    PlanStage stage = batchPlanService.getStageByBatchPlanAndStageName(plan, "生产装配");
                    workOrderInforEx.setPlanManufactStartDate(stage.getStagePlanStartTime());
                    workOrderInforEx.setPlanManufactEndDate(stage.getStagePlanEndTime());
                    workOrderInforEx.setBatchDeliveryDate(plan.getBatchDeliveryDate());
                }



                return workOrderInforEx;
            }
        });

        List<WorkOrderInforEx> content = page2.getContent();
        List<Date> batchDeliveryDate = new ArrayList<>();
        List<Date> planend=new ArrayList<>();
        for(WorkOrderInforEx map:content)
        {
            if (map.getPlanManufactEndDate()!=null) {
                batchDeliveryDate.add(map.getBatchDeliveryDate());
                planend.add(map.getCloseTime());
            }
        }
        int total=content.size();
        double[] arrlist = new double[13];
        for(int z=0;z<batchDeliveryDate.size();z++){
            if (batchDeliveryDate.get(z)!=null&&planend.get(z)!=null) {
                if (batchDeliveryDate.get(z).after(planend.get(z))) {
                    String a = String.valueOf(batchDeliveryDate.get(z));
                    arrlist[Integer.parseInt(a.substring(5, 7)) + 1] += 1;
                }
            }
        }
        for (int i = 0; i < arrlist.length; i++) {
            arrlist[i] /= total;
        }
        return arrlist;
    }


    @Autowired
    private PlantCapacityCalendarRepository plantCapacityCalendarRepository;
    @Resource(name = "plantCapacityCalendarMapperExImpl")
    private PlantCapacityCalendarMapperEx plantCapacityCalendarExMapper;

    @Override
    public Map<String, Object> getReportformsPlantCapacityCalendarByPage() {
        PageEntity pageEntity = new PageEntity();
        pageEntity.setCurrent(1);
        double inf = Double.POSITIVE_INFINITY;
        pageEntity.setPageSize((int) inf);
        pageEntity.setSorters(new ArrayList<>());
        pageEntity.setFilters(new ArrayList<>());
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<PlantCapacityCalendar> page = plantCapacityCalendarRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(PlantCapacityCalendar_.delete), 0); //过滤为0
                    list.add(pre2);
//                    Predicate pre3 = criteriaBuilder.equal(root.get(PlantCapacityCalendar_.workHour), 0); //过滤为0
//                    list.add(pre3);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(PlantCapacityCalendar_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<PlantCapacityCalendarEx> page1 = page.map(plantCapacityCalendarExMapper::toEntity);
        List<PlantCapacityCalendarEx> content = page1.getContent();
        Map<String, Map<String, Float>> processNameYearMonthRealWorkHourSums = new HashMap<>();
        Map<String, Map<String, Float>> processNameYearMonthWorkHourSums = new HashMap<>();

        for (PlantCapacityCalendarEx element : content) {
            String processName = element.getProcessName();
            String date = String.valueOf(element.getDate());
            String yearMonth = date.substring(0, 7); // 获取年份和月份部分
            Float realWorkHour = element.getRealWorkHour();
            Float workHour = element.getWorkHour();

            if (processNameYearMonthRealWorkHourSums.containsKey(processName)) {
                // 如果已经存在该processName，则获取对应的年份和月份及对应的realWorkHourSums
                Map<String, Float> yearMonthRealWorkHourSums = processNameYearMonthRealWorkHourSums.get(processName);
                if (yearMonthRealWorkHourSums.containsKey(yearMonth)) {
                    // 如果已经存在该年份和月份，则将其对应的realWorkHour累加
                    yearMonthRealWorkHourSums.put(yearMonth, yearMonthRealWorkHourSums.get(yearMonth) + realWorkHour);
                } else {
                    // 如果不存在该年份和月份，则将其添加到yearMonthRealWorkHourSums，并将realWorkHour设置为初始值0
                    yearMonthRealWorkHourSums.put(yearMonth, realWorkHour);
                }
            } else {
                // 如果不存在该processName，则将其添加到processNameYearMonthRealWorkHourSums，并创建对应的年份和月份及初始值0
                Map<String, Float> yearMonthRealWorkHourSums = new HashMap<>();
                yearMonthRealWorkHourSums.put(yearMonth, realWorkHour);
                processNameYearMonthRealWorkHourSums.put(processName, yearMonthRealWorkHourSums);
            }

            if (processNameYearMonthWorkHourSums.containsKey(processName)) {
                // 如果已经存在该processName，则获取对应的年份和月份及对应的workHourSums
                Map<String, Float> yearMonthWorkHourSums = processNameYearMonthWorkHourSums.get(processName);
                if (yearMonthWorkHourSums.containsKey(yearMonth)) {
                    // 如果已经存在该年份和月份，则将其对应的workHour累加
                    yearMonthWorkHourSums.put(yearMonth, yearMonthWorkHourSums.get(yearMonth) + workHour);
                } else {
                    // 如果不存在该年份和月份，则将其添加到yearMonthWorkHourSums，并将workHour设置为初始值0
                    yearMonthWorkHourSums.put(yearMonth, workHour);
                }
            } else {
                // 如果不存在该processName，则将其添加到processNameYearMonthWorkHourSums，并创建对应的年份和月份及初始值0
                Map<String, Float> yearMonthWorkHourSums = new HashMap<>();
                yearMonthWorkHourSums.put(yearMonth, workHour);
                processNameYearMonthWorkHourSums.put(processName, yearMonthWorkHourSums);
            }
        }
        // 用于存储相除结果的两个嵌套Map
        Map<String, Map<String, Float>> processNameYearMonthWorkHourRatios = new HashMap<>();
        // 计算 processNameYearMonthWorkHourRatios
        for (Map.Entry<String, Map<String, Float>> entry1 : processNameYearMonthRealWorkHourSums.entrySet()) {
            String processName = entry1.getKey();
            Map<String, Float> yearMonthRealWorkHourSums = entry1.getValue();
            Map<String, Float> yearMonthWorkHourSums = processNameYearMonthWorkHourSums.getOrDefault(processName, new HashMap<>());
            Map<String, Float> yearMonthWorkHourRatios = new HashMap<>();

            for (Map.Entry<String, Float> entry2 : yearMonthRealWorkHourSums.entrySet()) {
                String yearMonth = entry2.getKey();
                Float realWorkHourSum = entry2.getValue();
                Float workHourSum = yearMonthWorkHourSums.getOrDefault(yearMonth, (float) 0);

                if (realWorkHourSum != (float) 0 && workHourSum != (float) 0) {
                    Float ratio = workHourSum / realWorkHourSum;
                    yearMonthWorkHourRatios.put(yearMonth, ratio);
                } else {
                    yearMonthWorkHourRatios.put(yearMonth, (float) Double.NaN); // 使用 NaN 表示无效的比率值
                }
            }
            processNameYearMonthWorkHourRatios.put(processName, yearMonthWorkHourRatios);
        }
        List<String> processList = new ArrayList<>(processNameYearMonthWorkHourRatios.keySet());
        List series = new ArrayList<>();
        for(int j = 0;j<processList.size();j++){
            Map<String, Float> element = processNameYearMonthWorkHourRatios.get(processList.get(j));
            List<Float> dataList = extractData(element);
            System.out.println(generateJson(processList.get(j), dataList));
            series.add(generateJson(processList.get(j), dataList));
        }

        Map<String, Object> list1 = new HashMap<>();
        list1.put("FStaff", processList);
        Map<String, Object> label = new HashMap<>();
        label.put("formatter", "目标值70%");
        label.put("show", true);
        label.put("position", "end");
        list1.put("label",label);
        list1.put("series", series );
        return list1;

    }
    public Map<String, Object> getReportformsPlantCapacityCalendarByPage2() {
        PageEntity pageEntity = new PageEntity();
        pageEntity.setCurrent(1);
        double inf = Double.POSITIVE_INFINITY;
        pageEntity.setPageSize((int) inf);
        pageEntity.setSorters(new ArrayList<>());
        pageEntity.setFilters(new ArrayList<>());
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<PlantCapacityCalendar> page = plantCapacityCalendarRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(PlantCapacityCalendar_.delete), 0); //过滤为0
                    list.add(pre2);
//                    Predicate pre3 = criteriaBuilder.equal(root.get(PlantCapacityCalendar_.workHour), 0); //过滤为0
//                    list.add(pre3);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(PlantCapacityCalendar_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<PlantCapacityCalendarEx> page1 = page.map(plantCapacityCalendarExMapper::toEntity);
        List<PlantCapacityCalendarEx> content = page1.getContent();
        Map<String, Map<String, Float>> processNameYearMonthRealWorkHourSums = new HashMap<>();
        Map<String, Map<String, Float>> processNameYearMonthWorkHourSums = new HashMap<>();

        for (PlantCapacityCalendarEx element : content) {
            String processName = element.getProcessName();
            String date = String.valueOf(element.getDate());
            String yearMonth = date.substring(0, 7); // 获取年份和月份部分
            Float realWorkHour = element.getRealWorkHour();
            Float workHour = element.getWorkHour();

            if (processNameYearMonthRealWorkHourSums.containsKey(processName)) {
                // 如果已经存在该processName，则获取对应的年份和月份及对应的realWorkHourSums
                Map<String, Float> yearMonthRealWorkHourSums = processNameYearMonthRealWorkHourSums.get(processName);
                if (yearMonthRealWorkHourSums.containsKey(yearMonth)) {
                    // 如果已经存在该年份和月份，则将其对应的realWorkHour累加
                    yearMonthRealWorkHourSums.put(yearMonth, yearMonthRealWorkHourSums.get(yearMonth) + realWorkHour);
                } else {
                    // 如果不存在该年份和月份，则将其添加到yearMonthRealWorkHourSums，并将realWorkHour设置为初始值0
                    yearMonthRealWorkHourSums.put(yearMonth, realWorkHour);
                }
            } else {
                // 如果不存在该processName，则将其添加到processNameYearMonthRealWorkHourSums，并创建对应的年份和月份及初始值0
                Map<String, Float> yearMonthRealWorkHourSums = new HashMap<>();
                yearMonthRealWorkHourSums.put(yearMonth, realWorkHour);
                processNameYearMonthRealWorkHourSums.put(processName, yearMonthRealWorkHourSums);
            }

            if (processNameYearMonthWorkHourSums.containsKey(processName)) {
                // 如果已经存在该processName，则获取对应的年份和月份及对应的workHourSums
                Map<String, Float> yearMonthWorkHourSums = processNameYearMonthWorkHourSums.get(processName);
                if (yearMonthWorkHourSums.containsKey(yearMonth)) {
                    // 如果已经存在该年份和月份，则将其对应的workHour累加
                    yearMonthWorkHourSums.put(yearMonth, yearMonthWorkHourSums.get(yearMonth) + workHour);
                } else {
                    // 如果不存在该年份和月份，则将其添加到yearMonthWorkHourSums，并将workHour设置为初始值0
                    yearMonthWorkHourSums.put(yearMonth, workHour);
                }
            } else {
                // 如果不存在该processName，则将其添加到processNameYearMonthWorkHourSums，并创建对应的年份和月份及初始值0
                Map<String, Float> yearMonthWorkHourSums = new HashMap<>();
                yearMonthWorkHourSums.put(yearMonth, workHour);
                processNameYearMonthWorkHourSums.put(processName, yearMonthWorkHourSums);
            }
        }
        Map<String, Map<String, Float>> processNameYearMonthWorkHourRatios = new HashMap<>();
        // 遍历外层Map的每个键值对
        for (Map.Entry<String, Map<String, Float>> entry : processNameYearMonthRealWorkHourSums.entrySet()) {
            String processName = entry.getKey();
            Map<String, Float> yearMonthWorkHourSums = entry.getValue();

            // 遍历内层Map的每个键值对
            for (Map.Entry<String, Float> innerEntry : yearMonthWorkHourSums.entrySet()) {
                String yearMonth = innerEntry.getKey();
                Float workHourSum = innerEntry.getValue();

                // 将workHourSum除以1.76
                Float result = (float) (workHourSum / 1.76);

                // 更新内层Map的值
                yearMonthWorkHourSums .put(yearMonth, result);
            }
            processNameYearMonthWorkHourRatios.put(processName, yearMonthWorkHourSums);
            // 更新外层Map的值
        }
        List<String> processList = new ArrayList<>(processNameYearMonthWorkHourRatios.keySet());
        List series = new ArrayList<>();
        for(int j = 0;j<processList.size();j++){
            Map<String, Float> element = processNameYearMonthWorkHourRatios.get(processList.get(j));
            List<Float> dataList = extractData(element);
            System.out.println(generateJson(processList.get(j), dataList));
            series.add(generateJson(processList.get(j), dataList));
        }

        Map<String, Object> list1 = new HashMap<>();
        list1.put("FStaff", processList);
        Map<String, Object> label = new HashMap<>();
        label.put("formatter", "目标值70%");
        label.put("show", true);
        label.put("position", "end");
        list1.put("label",label);
        list1.put("series", series );
        return list1;

    }
    @Autowired
    private PickingTaskMapperEx pickingTaskExMapper;
    @Autowired
    private PickingTaskRepository pickingTaskRepository;
    public List<Map<String, Object>> getReportformsPickingTaskByPage() {
        PageEntity pageEntity = new PageEntity();
        pageEntity.setCurrent(1);
        double inf = Double.POSITIVE_INFINITY;
        pageEntity.setPageSize((int) inf);
        pageEntity.setSorters(new ArrayList<>());
        pageEntity.setFilters(new ArrayList<>());
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() -1,
                pageEntity.getPageSize());
        Page<PickingTask> page = pickingTaskRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 =   JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(PickingTask_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if(pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(PickingTask_.createTime).as(Date.class)));
                    }
                    return  criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<PickingTaskEx> page1 = page.map(pickingTaskExMapper::toEntity);
        List<PickingTaskEx> content = page1.getContent();
        List<String> time = new ArrayList<>();
        List<String> state = new ArrayList<>();
        List<String> finish = new ArrayList<>();
        for (PickingTaskEx map : content) {
            time.add(String.valueOf(map.getCreateTime()));
            state.add(map.getPickingState());
            finish.add(String.valueOf(map.getPickingFinishTime()));
        }
        Map<String, Integer> monthCounts = new HashMap<>();
        Map<String, Integer> monthDistributedCounts = new HashMap<>();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S");
        for (int i = 0; i < time.size(); i++) {
            LocalDateTime dateTime = LocalDateTime.parse(time.get(i), formatter);
            String month = String.format("%02d", dateTime.getMonthValue());
            String yearMonth = dateTime.getYear() + "-" + month;

            if (!state.get(i).equals("已分料")) {
                monthCounts.put(yearMonth, monthCounts.getOrDefault(yearMonth, 0) + 1);
            } else if (state.get(i).equals("已分料")) {
                monthCounts.put(yearMonth, monthCounts.getOrDefault(yearMonth, 0) + 1);
                monthDistributedCounts.put(yearMonth, monthDistributedCounts.getOrDefault(yearMonth, 0) + 1);
            }
        }
        List<String> newtime = new ArrayList<>();
        List<Integer> newdistributedCount = new ArrayList<>();
        List<Integer> newtotalCount = new ArrayList<>();
        List<Double> newdistributedPercentage = new ArrayList<>();

        for (Map.Entry<String, Integer> entry : monthCounts.entrySet()) {
            String yearMonth = entry.getKey();
            int totalCount = entry.getValue();
            int distributedCount = monthDistributedCounts.getOrDefault(yearMonth, 0);
            int undistributedCount = totalCount - distributedCount;

            double distributedPercentage = (double) distributedCount / totalCount * 100;
            newtime.add(yearMonth);
            newdistributedCount.add(distributedCount);
            newtotalCount.add(totalCount);
            newdistributedPercentage.add(distributedPercentage);
        }
        List<Map<String, Object>> varList1 = new ArrayList<>();
        for (int i = 0; i < newtime.size(); i++) {
            Map<String, Object> map = new HashMap<>();
            map.put("Fmonth", Integer.parseInt(newtime.get(i).substring(5)));
            map.put("FNUM2", newdistributedCount.get(i));
            map.put("FNUM1", newtotalCount.get(i));
            map.put("Fpecent", newdistributedPercentage.get(i));
            varList1.add(map);
        }
        System.out.println(newtime);
        System.out.println(newdistributedCount);
        System.out.println(newtotalCount);
        System.out.println(newdistributedPercentage);
        return varList1;

    }
    @Autowired
    private ProductManufactInforRepository productManufactInforRepository;
    @Autowired
    private ProductManufactInforMapperEx productManufactInforExMapper;
    @Override
    public Map<String, Object> getReportformsProductManufactInforExecuteByPage() {
        PageEntity pageEntity = new PageEntity();
        pageEntity.setCurrent(1);
        double inf = Double.POSITIVE_INFINITY;
        pageEntity.setPageSize((int) inf);
        pageEntity.setSorters(new ArrayList<>());
        pageEntity.setFilters(new ArrayList<>());
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<ProductManufactInfor> page = productManufactInforRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate[] p = new Predicate[list.size()];
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<ProductManufactInforEx> page1 = page.map(productManufactInforExMapper::toEntity);
        List<ProductManufactInforEx> content = page1.getContent();
        List<String> fact_start = new ArrayList<>();
        List<String> processname = new ArrayList<>();
        List<String> fact_end = new ArrayList<>();
        List<String> end = new ArrayList<>();
        List<Date> start   = new ArrayList<>();

        for (ProductManufactInforEx map : content) {
                if (String.valueOf(map.getManufactEndDate())!="null")
                {
                    fact_end.add(String.valueOf(map.getManufactEndDate()));
                    processname.add(map.getProcessName());
                    fact_start.add(String.valueOf(map.getManufactStartDate()));
                    start.add(map.getPlanManufactStartDate());
                    end.add(String.valueOf(map.getPlanManufactEndDate()));
                }
        }
        Map<String, Map<String, Float>> completionRate = calculateCompletionRate(processname, fact_end, end);
        for (Map.Entry<String, Map<String, Float>> entry : completionRate.entrySet()) {
            String process = entry.getKey();
            Map<String, Float> rateMap = entry.getValue();
            for (Map.Entry<String, Float> rateEntry : rateMap.entrySet()) {
                String month = rateEntry.getKey();
                Float rate = rateEntry.getValue();
                System.out.println("工序：" + process + "，月份：" + month + "，按时完成占比：" + rate);
            }
        }
        List<String> processList = new ArrayList<>(completionRate.keySet());
        List series = new ArrayList<>();
        for(int j = 0;j<processList.size();j++){
            Map<String, Float> element = completionRate.get(processList.get(j));
            List<Float> dataList = extractData(element);
            series.add(generateJson(processList.get(j), dataList));
        }

        Map<String, Object> list1 = new HashMap<>();
        list1.put("FStaff", processList);
        Map<String, Object> label = new HashMap<>();
        label.put("formatter", "目标值70%");
        label.put("show", true);
        label.put("position", "end");
        list1.put("label",label);
        list1.put("series", series );
        return list1;
    }
    public static Map<String, Map<String, Float>> calculateCompletionRate(List<String> processname, List<String> fact_end, List<String> end) {
        Map<String, Map<String, Float>> completionRate = new HashMap<>();

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        for (int i = 0; i < processname.size(); i++) {
            String process = processname.get(i);
            String factEnd = fact_end.get(i);
            String endDate = end.get(i);

            try {
                String month = getMonth(factEnd);

                if (!completionRate.containsKey(process)) {
                    completionRate.put(process, new HashMap<>());
                }
                Map<String, Float> rateMap = completionRate.get(process);

                if (!rateMap.containsKey(month)) {
                    rateMap.put(month, 0.0F);
                }

                if (format.parse(factEnd).compareTo(format.parse(endDate)) <= 0) {
                    double rate = rateMap.get(month);
                    rateMap.put(month, (float) (rate + 1));
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }

        for (Map.Entry<String, Map<String, Float>> entry : completionRate.entrySet()) {
            Map<String, Float> rateMap = entry.getValue();
            for (Map.Entry<String, Float> rateEntry : rateMap.entrySet()) {
                String month = rateEntry.getKey();
                double total = processname.stream().filter(process -> completionRate.get(process).containsKey(month)).count();
                double rate = rateEntry.getValue() / total;
                rateMap.put(month, (float) rate);
            }
        }

        return completionRate;
    }


    @Autowired
    private CabinetQualityRepository cabinetQualityRepository;
    @Override
    public List<Double>  getReportformsCabinetQuality(){
        PageEntity pageEntity = new PageEntity();
        pageEntity.setCurrent(1);
        double inf = Double.POSITIVE_INFINITY;
        pageEntity.setPageSize((int) inf);
        pageEntity.setSorters(new ArrayList<>());
        pageEntity.setFilters(new ArrayList<>());
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<CabinetQuality> page = cabinetQualityRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate[] p = new Predicate[list.size()];
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<CabinetQuality> page1 = page;
        List<CabinetQuality> content = page1.getContent();
        List<Integer> linecount=new ArrayList<>();
        List<Integer> errorlinecount=new ArrayList<>();
        List<Date> inspecttime=new ArrayList<>();
        for(CabinetQuality map : content)
        {
            linecount.add(map.getLineCount());
            errorlinecount.add(map.getErrorLineCount());
            inspecttime.add(map.getInspectTime());
        }
        Map<Integer, Integer> errorCountByMonth = new HashMap<>();
        Map<Integer, Integer> totalCountByMonth = new HashMap<>();
        for (int i = 0; i < inspecttime.size(); i++) {
            Date date = inspecttime.get(i);
            if (date != null) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(date);
                int month = calendar.get(Calendar.MONTH) + 1;
                errorCountByMonth.put(month, errorCountByMonth.getOrDefault(month, 0) + errorlinecount.get(i));
                totalCountByMonth.put(month, totalCountByMonth.getOrDefault(month, 0) + linecount.get(i));
            }
        }
        Map<Integer, Double> errorRateByMonth = new HashMap<>();
        for (Integer month : errorCountByMonth.keySet()) {
            int errorCount = errorCountByMonth.get(month);
            int totalCount = totalCountByMonth.get(month);
            double errorRate = (double) errorCount / totalCount;
            errorRateByMonth.put(month, errorRate);
        }
        double[] arr = new double[13];
        for (Map.Entry<Integer, Double> entry : errorRateByMonth.entrySet()) {
            int index = entry.getKey();
            double value = entry.getValue();
            arr[index] = value*100;
        }
        List<Double> list = new ArrayList<>();
        for (double d : arr) {
            list.add(d);
        }
        return list;
    }
    @Autowired
    private CustomComplaintRepository customComplaintRepository;
    @Override
    public List<Double>  getReportformsCustomComplaint() {
        PageEntity pageEntity = new PageEntity();
        pageEntity.setCurrent(1);
        double inf = Double.POSITIVE_INFINITY;
        pageEntity.setPageSize((int) inf);
        pageEntity.setSorters(new ArrayList<>());
        pageEntity.setFilters(new ArrayList<>());
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<CustomComplaint> page = customComplaintRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate[] p = new Predicate[list.size()];
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<CustomComplaint> page1 = page;
        List<CustomComplaint> content = page1.getContent();
        List<Integer> bugcount = new ArrayList<>();
        List<Date> time = new ArrayList<>();
        for (CustomComplaint map : content) {
            bugcount.add(map.getBugCount());
            time.add(map.getCreateTime());
        }
        Pageable pageable2 = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<PlantCapacityCalendar> page2 = plantCapacityCalendarRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(PlantCapacityCalendar_.delete), 0); //过滤为0
                    list.add(pre2);
//                    Predicate pre3 = criteriaBuilder.equal(root.get(PlantCapacityCalendar_.workHour), 0); //过滤为0
//                    list.add(pre3);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(PlantCapacityCalendar_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable2);
        Page<PlantCapacityCalendar> page3 = page2;
        List<PlantCapacityCalendar> content2 = page3.getContent();
        List<Float> workHours = new ArrayList<>();
        List<String> times = new ArrayList<>();
        for (PlantCapacityCalendar map : content2) {
            workHours.add(map.getRealWorkHour());
            times.add(String.valueOf(map.getDate()));
        }
        double[] workHourArray = workHours.stream().mapToDouble(Float::floatValue).toArray();
        Map<YearMonth, Double> workTimeMap = new HashMap<>();
        List<LocalDateTime> dateTimeList = new ArrayList<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S");
        for (String dateTime : times) {
            LocalDateTime localDateTime = LocalDateTime.parse(dateTime, formatter);
            dateTimeList.add(localDateTime);
        }
        for (int i = 0; i < times.size(); i++) {
            LocalDateTime dateTime = dateTimeList.get(i);
            double workHour = workHourArray[i];
            YearMonth yearMonth = YearMonth.from(dateTime);
            workTimeMap.put(yearMonth, workTimeMap.getOrDefault(yearMonth, 0.0) + workHour);
        }
        Map<Integer, Integer> mergedMap = new HashMap<>();
        for (int i = 0; i < bugcount.size(); i++) {
            int month = getMonthFromDate(time.get(i));
            int count = bugcount.get(i);
            mergedMap.put(month, mergedMap.getOrDefault(month, 0) + count);
        }
        System.out.println(workTimeMap);
        System.out.println(mergedMap);
        System.out.println(time);
        Map<YearMonth, Double> resultMap = new HashMap<>();

        for (Map.Entry<YearMonth, Double> entry : workTimeMap.entrySet()) {
            YearMonth yearMonth = entry.getKey();
            Double workTime = entry.getValue();

            int month = yearMonth.getMonthValue();
            Integer mergedValue = mergedMap.get(month);

            if (mergedValue != null) {
                double result = mergedValue / workTime*0.001;
                resultMap.put(yearMonth, result);
            }
        }
        Map<Integer, Double> resultMapByMonth = new HashMap<>();
        for (Map.Entry<YearMonth, Double> entry : resultMap.entrySet()) {
            int month = entry.getKey().getMonth().getValue();
            double value = entry.getValue();
            resultMapByMonth.put(month, value);
        }
        double[] arr = new double[13];
        for (Map.Entry<Integer, Double> entry : resultMapByMonth.entrySet()) {
            int index = entry.getKey();
            double value = entry.getValue();
            arr[index] = value;
        }
        List<Double> list = new ArrayList<>();
        for (double d : arr) {
            list.add(d);
        }
        return list;
    }

    public List<Map<String, Object>> getReportformsWorkOrderInforByPage2() {
        PageEntity pageEntity = new PageEntity();
        pageEntity.setCurrent(1);
        double inf = Double.POSITIVE_INFINITY;
        pageEntity.setPageSize((int) inf);
        pageEntity.setSorters(new ArrayList<>());
        pageEntity.setFilters(new ArrayList<>());
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<WorkOrderInfor> page = workOrderInforRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {


                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(WorkOrderInfor_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(WorkOrderInfor_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<WorkOrderInforEx> page1 = page.map(workOrderInforExMapper::toEntity);
        List<WorkOrderInforEx> content = page1.getContent();
        List<String> time = new ArrayList<>();
        List<Integer> state = new ArrayList<>();
        List<String> finish = new ArrayList<>();
        for (WorkOrderInforEx map : content) {
            time.add(String.valueOf(map.getCreateTime()));
            state.add(map.getIsFileKitting());
        }
        Map<String, Integer> monthCounts = new HashMap<>();
        Map<String, Integer> monthDistributedCounts = new HashMap<>();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S");
        for (int i = 0; i < time.size(); i++) {
            LocalDateTime dateTime = LocalDateTime.parse(time.get(i), formatter);
            String month = String.format("%02d", dateTime.getMonthValue());
            String yearMonth = dateTime.getYear() + "-" + month;

            if (state.get(i) == null ||state.get(i)==0) {
                monthCounts.put(yearMonth, monthCounts.getOrDefault(yearMonth, 0) + 1);
            } else if (state.get(i)==1) {
                monthCounts.put(yearMonth, monthCounts.getOrDefault(yearMonth, 0) + 1);
                monthDistributedCounts.put(yearMonth, monthDistributedCounts.getOrDefault(yearMonth, 0) + 1);
            }
        }
        List<String> newtime = new ArrayList<>();
        List<Integer> newdistributedCount = new ArrayList<>();
        List<Integer> newtotalCount = new ArrayList<>();
        List<Double> newdistributedPercentage = new ArrayList<>();

        for (Map.Entry<String, Integer> entry : monthCounts.entrySet()) {
            String yearMonth = entry.getKey();
            int totalCount = entry.getValue();
            int distributedCount = monthDistributedCounts.getOrDefault(yearMonth, 0);
            int undistributedCount = totalCount - distributedCount;

            double distributedPercentage = (double) distributedCount / totalCount * 100;
            newtime.add(yearMonth);
            newdistributedCount.add(distributedCount);
            newtotalCount.add(totalCount);
            newdistributedPercentage.add(distributedPercentage);
        }
        List<Map<String, Object>> varList1 = new ArrayList<>();
        for (int i = 0; i < newtime.size(); i++) {
            Map<String, Object> map = new HashMap<>();
            map.put("Fmonth", Integer.parseInt(newtime.get(i).substring(5)));
            map.put("FNUM2", newdistributedCount.get(i));
            map.put("FNUM1", newtotalCount.get(i));
            map.put("Fpecent", newdistributedPercentage.get(i));
            varList1.add(map);
        }
        System.out.println(newtime);
        System.out.println(newdistributedCount);
        System.out.println(newtotalCount);
        System.out.println(newdistributedPercentage);
        return varList1;


    }


    @Override
    public double[] getReportformsCustomComplaint2() {
        PageEntity pageEntity = new PageEntity();
        pageEntity.setCurrent(1);
        double inf = Double.POSITIVE_INFINITY;
        pageEntity.setPageSize((int) inf);
        pageEntity.setSorters(new ArrayList<>());
        pageEntity.setFilters(new ArrayList<>());
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<CustomComplaint> page = customComplaintRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate[] p = new Predicate[list.size()];
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<CustomComplaint> page1 = page;
        List<CustomComplaint> content = page1.getContent();
        int[] bugcount = new int[13];
        List<String> time = new ArrayList<>();
        for (CustomComplaint map : content) {
            if(map.getCreateTime()!=null)
            time.add(String.valueOf(map.getCreateTime()));
        }
        for(int z=0;z<13;z++)
        {
            bugcount[z]=0;
        }
        for(int z=0;z<time.size();z++)
        {
            int temp=Integer.parseInt(time.get(z).substring(5, 7));
            bugcount[temp]+=1;
        }
        Pageable  pageable2 = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<WorkOrderInfor> page2 = workOrderInforRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {


                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(WorkOrderInfor_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(WorkOrderInfor_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable2);
        Page<WorkOrderInforEx> page3 = page2.map(workOrderInforExMapper::toEntity);
        List<WorkOrderInforEx> content2 = page3.getContent();
        int[] total = new int[13];
        List<String> month = new ArrayList<>();
        for (WorkOrderInforEx map : content2) {
            if(map.getReleaseTime()!=null)
                month.add(String.valueOf(map.getReleaseTime()));
        }
        for(int z=0;z<13;z++)
        {
            total[z]=0;
        }
        for(int z=0;z<month.size();z++)
        {
            int temp=Integer.parseInt(month.get(z).substring(5, 7));
            total[temp]+=1;
        }
        double[] list = new double[13];
        for(int z=0;z<13;z++)
        {
            if(total[z]!=0)
            list[z]=bugcount[z]*100.0/total[z];
            else list[z]=0;
        }
        return list;
    }

    private static int getMonthFromDate(Date date) {
        LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        return localDate.getMonthValue();
    }
    public static String getMonth(String date) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat monthFormat = new SimpleDateFormat("yyyy-MM");
        return monthFormat.format(format.parse(date));
    }
    public static Map<String, Object> generateJson(String value, List<Float> data) {
        Map<String, Object> json = new HashMap<>();
        List<Float> dataList = new ArrayList<>();
        for (Float num : data) {
            dataList.add(num);
        }
        json.put("data", dataList);
        json.put("name", value);
        return json;
    }
        public static List<Float> extractData(Map<String, Float> map) {
            List<Float> dataList = new ArrayList<>();

            // 获取当前年份
            int currentYear = java.time.Year.now().getValue();

            // 根据当前年份构造12个月份
            List<String> months = new ArrayList<>();
            for (int i = 1; i <= 13; i++) {
                String month = String.format("%04d-%02d", currentYear, i);
                months.add(month);
            }

            // 遍历月份，将对应的值填充进list中
            for (String month : months) {
                Float value = map.getOrDefault(month, Float.NaN);
                if (Float.isNaN(value)) {
                    dataList.add(0f);
                } else {
                    dataList.add(value);
                }
            }

            return dataList;
        }

}

